﻿using System.Diagnostics;
using System.Xml.Serialization;
using ZOIL.DataModel;
using System.Linq;

namespace ZOIL.Library.Components
{
    public class ZPortal : InformationObjectBase, ICustomUpdateable, INotifyObjectRemotelyCreated
    {
        private bool _isMagicLense;
        private bool _isInitialized;

        #region ctor

        public ZPortal()
        {
            IsMagicLense = false;
            IsInitialized = false;
        }

        #endregion

        #region public properties

        #region IsMagicLense

        public bool IsMagicLense
        {
            get { return _isMagicLense; }
            set
            {
                if (value.Equals(_isMagicLense))
                {
                    return;
                }
                _isMagicLense = value;
                RaisePropertyChanged("IsMagicLense");
                OnObjectLocallyChanged();
            }
        }

        #endregion

        #region IsInitialized

        public bool IsInitialized
        {
            get { return _isInitialized; }
            set
            {
                if (value.Equals(_isInitialized))
                {
                    return;
                }
                _isInitialized = value;
                RaisePropertyChanged("IsInitialized");
                OnObjectLocallyChanged();
            }
        }

        #endregion

        #region PortalShape
        [XmlIgnore]
        private ZPortalShape _portalShape;
        [XmlIgnore]
        public ZPortalShape PortalShape
        {
            get
            {
                if (_portalShapeId != default(long))
                {
                    if (!(_portalShape != null && _portalShape.DatabaseId == _portalShapeId))
                    {
                        _portalShape = (ZPortalShape) DatabaseCollection.Collection.GetPersistable(_portalShapeId);
                    }
                    _portalShapeId = default(long);
                }

                return _portalShape;
            }
            set
            {
                _portalShapeId = default(long);
                if (Equals(value, _portalShape))
                {
                    return;
                }
                _portalShape = value;
                RaisePropertyChanged("PortalShape");
                OnObjectLocallyChanged();
            }
        }
        [Db4oIgnore]
        private long _portalShapeId = default(long);
        [XmlElement("PortalShape")]
        public long PortalShapeId
        {
            get { return _portalShape == null ? default(long) : _portalShape.DatabaseId; }
            set
            {
                _portalShapeId = value;
            }
        }

        #endregion

        #endregion

        public override void OnRemoteUpdated()
        {
            RaisePropertyChanged("IsInitialized");
            RaisePropertyChanged("IsMagicLense");
            RaisePropertyChanged("PortalShape");
        }

        #region Implementation of ICustomUpdateable

        [XmlIgnore]
        [Db4oIgnore]
        private static readonly string[] _exculdedFields = new[] { LinksFieldName };

        [XmlIgnore]
        [Db4oIgnore]
        private readonly object _onUpdateLock = new object();
        /// <summary>
        ///     Called when a new remote update is received.
        ///     If a class does not implement this interface all fields will be exchanged
        ///     If a class implementens this interface it MUST handle the exchange on its own!
        /// </summary>
        /// <param name="remotelyUpdatedObject"> Object with the changed.Can be casted into the implementing class (: this.GetType() == <see
        ///      cref="remotelyUpdatedObject" /> .GetType()). </param>
        public virtual void OnUpdate(object remotelyUpdatedObject)
        {
            lock (_onUpdateLock)
            {
                var u = (ZPortal)remotelyUpdatedObject;

                Debug.Assert(_exculdedFields.Contains(LinksFieldName));
                CustomUpdateLinks(u.Links);

                //und rest normal austauschen
                this.ExchangeFieldsOnFirstLevel(remotelyUpdatedObject, _exculdedFields);
            }
        }

        #endregion

        #region Implementation of INotifyObjectRemotelyCreated

        [XmlIgnore]
        [Db4oIgnore]
        private bool _wasRemotelyCreated = false;
        [XmlIgnore]
        public bool WasRemotelyCreated
        {
            get { return _wasRemotelyCreated; }
        }
        public virtual void OnRemotelyCreated()
        {
            _wasRemotelyCreated = true;
        }

        #endregion
    }
}